package com.example.maastock.ontime;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.maastock.common.HttpsUtils;
import com.example.maastock.entity.BookStockOnline;
import com.example.maastock.mapper.BookStockOnlineMapper;
import com.example.maastock.web.StockOnlineObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
/**
 * 实时监控
 */
public class SearchOnLine {


    @Autowired
    private BookStockOnlineMapper bookStockOnlineMapper;


    public Boolean saveBooksRecord(BookStockOnline bookStockOnline) {
        bookStockOnline.setBusinessDate(LocalDate.now());
        bookStockOnline.setCreateTime(LocalDateTime.now());
        bookStockOnline.setStatus(1);
        int insert = bookStockOnlineMapper.insert(bookStockOnline);
        return insert > 0;
    }


    public Object searchOnlineInTime(String code) {

        String resultUrl = "http://proxy.finance.qq.com/cgi/cgi-bin/fundflow/hsfundtab?code=" + code;
        JSONObject data = new JSONObject();

        try {
            URL url = new URL(resultUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            StringBuilder response = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            data = JSONObject.parseObject(response.toString());
            data = data.getJSONObject("data");
            Object todayFundTrend = data.get("todayFundTrend");
            Object historyFundFlow = data.get("historyFundFlow");
            JSONObject jsonObject = JSONObject.parseObject(todayFundTrend.toString());
            JSONObject oneDayklineListObj = JSONObject.parseObject(historyFundFlow.toString());
            JSONArray minList = jsonObject.getJSONArray("minList");
            JSONArray oneDayklineList = oneDayklineListObj.getJSONArray("oneDayKlineList");
            StockOnlineObject stockOnlineObject = new StockOnlineObject();



            if (!ObjectUtil.isEmpty(minList)){
                int size = minList.size();
                if (size!=0){
                    String minDetail = minList.get(size-1).toString();
//                    String minDetail = minList.get(0).toString();
                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode rootNode = mapper.readTree(minDetail);
                    String price = rootNode.get("Price").asText();
                    Object firstObj = minList.get(0).toString();
                    ObjectMapper firstMapper = new ObjectMapper();
                    JsonNode firstRootNode = firstMapper.readTree(firstObj.toString());
                    String firstPrice = firstRootNode.get("Price").asText();


                    Double v = getHistoryPriceLit(oneDayklineList).get(oneDayklineList.size() -2);
                    firstPrice = v.toString();
                    stockOnlineObject.setNowPrice(price);

                    stockOnlineObject.setFirstPrice(firstPrice);
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
                    stockOnlineObject.setNowTime(LocalTime.now().format(formatter));
//                    return stockOnlineObject;
                }

            }

//            if ( ! ObjectUtil.isEmpty(oneDayklineList)){
//                List<Double> historyPriceLit = getHistoryPriceLit(oneDayklineList);
//                historyPriceLit.add(Double.valueOf(stockOnlineObject.getNowPrice()));
//                // 短期EMA的周期，一般为12
//                int shortPeriod = 12;
//                // 长期EMA的周期，一般为26
//                int longPeriod = 26;
//                // DIF的平滑周期，一般为9
//                int difSmoothPeriod = 9;
//
//                List<Double> emaShort = calculateEMA(historyPriceLit, shortPeriod);
//                List<Double> emaLong = calculateEMA(historyPriceLit, longPeriod);
//
//                List<Double> dif = new ArrayList<>();
//                for (int i = 0; i < emaShort.size() && i < emaLong.size(); i++) {
//                    dif.add(emaShort.get(i) - emaLong.get(i));
//                }
//
//                List<Double> dea = calculateEMA(dif, difSmoothPeriod);
//
//                List<Double> macd = new ArrayList<>();
//                for (int i = 0; i < dif.size() && i < dea.size(); i++) {
//                    macd.add(2 * (dif.get(i) - dea.get(i)));
//                }
//                List<Integer> goldenCross = isGoldenCross(dif, dea);
//                List<Double> allGoldenPrice = new ArrayList<>();
//                for (Integer i : goldenCross ){
//                    Double v = historyPriceLit.get(i);
//                    allGoldenPrice.add(v);
//                }
//                double v = calculateAverage(allGoldenPrice);
//                stockOnlineObject.setGoldenPrice(v);
//
//            }
            return stockOnlineObject;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    public List<BookStockOnline> getAllList(){
        QueryWrapper<BookStockOnline> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda().eq(BookStockOnline::getStatus, 1);
        List<BookStockOnline> bookStockOnlines =
                bookStockOnlineMapper.selectList(queryWrapper);
        return bookStockOnlines;
    }



    public List<Double> getHistoryPriceLit (JSONArray historyFundFlow) throws JsonProcessingException {
        List<Double> list = new ArrayList<>();
        for (int i = 0; i < historyFundFlow.size(); i++) {
            Object object = historyFundFlow.get(i);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(object.toString());
            String text = rootNode.get("price").asText();
            list.add(Double.valueOf(text));
        }
//        if (list.size() > 10) {
//            list = list.subList(list.size() - 10, list.size());
//        }
        return list;
    }


    public static List<Double> calculateEMA(List<Double> prices, int period) {
        List<Double> ema = new ArrayList<>();
        double multiplier = 2.0 / (period + 1);
        // 初始值取第一个价格
        ema.add(prices.get(0));
        for (int i = 1; i < prices.size(); i++) {
            double emaValue = (prices.get(i) - ema.get(i - 1)) * multiplier + ema.get(i - 1);
            ema.add(emaValue);
        }
        return ema;
    }


    public static List<Integer> isGoldenCross(List<Double> dif, List<Double> dea) {
        List<Integer> goldenCrosses = new ArrayList<>();
        for (int i = 1; i < dif.size(); i++) {
            if (dif.get(i - 1) <= dea.get(i - 1) && dif.get(i) > dea.get(i)) {
                goldenCrosses.add(i);
            }
        }
        return goldenCrosses;
    }


    public static double calculateAverage(List<Double> numberList) {
        if (numberList == null || numberList.isEmpty()) {
            return 0.0;
        }
        double sum = 0.0;
        for (Double number : numberList) {
            if (number!= null) { // 增加对列表元素为 null 的处理
                sum += number;
            }
        }
        return sum / numberList.size();
    }
}
